---
title: Linking
description: Link resources together and access them in a typesafe and secure way.
---

import { Tabs, TabItem } from '@astrojs/starlight/components';
import VideoAside from "../../../components/VideoAside.astro";

Resource Linking  allows you to access your **infrastructure** in your **runtime code** in a typesafe and secure way.

<VideoAside title="Watch a video on linking resources" href="https://youtu.be/s8cWklU4Akw" />

1. Create a resource that you want to link to. For example, a bucket.

   ```ts title="sst.config.ts" {6,11}
   const bucket = new sst.aws.Bucket("MyBucket");
   ```

2. Link it to your function or frontend, using the `link` prop.

   <Tabs>
     <TabItem label="Next.js">
     ```ts title="sst.config.ts" {2}
     new sst.aws.Nextjs("MyWeb", {
       link: [bucket]
     });
     ```
     </TabItem>
     <TabItem label="Remix">
     ```ts title="sst.config.ts" {2}
     new sst.aws.Remix("MyWeb", {
       link: [bucket]
     });
     ```
     </TabItem>
     <TabItem label="Astro">
     ```ts title="sst.config.ts" {2}
     new sst.aws.Astro("MyWeb", {
       link: [bucket]
     });
     ```
     </TabItem>
     <TabItem label="Function">
     ```ts title="sst.config.ts" {3}
     new sst.aws.Function("MyFunction", {
       handler: "src/lambda.handler",
       link: [bucket]
     });
     ```
     </TabItem>
   </Tabs>

3. Use the [SDK](/docs/reference/sdk/) to access the linked resource in your runtime in a typesafe way.

   <Tabs>
     <TabItem label="Next.js">
     ```js title="app/page.tsx"
     import { Resource } from "sst";

     console.log(Resource.MyBucket.name);
     ```
     </TabItem>
     <TabItem label="Remix">
     ```js title="app/routes/_index.tsx"
     import { Resource } from "sst";

     console.log(Resource.MyBucket.name);
     ```
     </TabItem>
     <TabItem label="Astro">
     ```astro title="src/pages/index.astro"
     ---
     import { Resource } from "sst";

     console.log(Resource.MyBucket.name);
     ---
     ```
     </TabItem>
     <TabItem label="Function">
     ```js title="src/lambda.ts"
     import { Resource } from "sst";

     console.log(Resource.MyBucket.name);
     ```
     </TabItem>
   </Tabs>

   :::tip
   The SDK currently supports JS/TS, Python, Golang, and Rust.
   :::

Learn how to use the SDK in [Python](/docs/reference/sdk/#python), [Golang](/docs/reference/sdk/#golang), and [Rust](/docs/reference/sdk/#rust).

---

### Working locally

The above applies to your app deployed through `sst deploy`.

To access linked resources locally you'll need to be running `sst dev`. By default, the `sst dev` CLI runs a multiplexer that also starts your frontend for you. This loads all your linked resources in the environment. Read more about [`sst dev`](/docs/reference/cli/#dev).

However if you are not using the multiplexer.

```bash frame="none"
sst dev --mode=basic
```

You'll need to wrap your frontend's dev command with the `sst dev` command.

<Tabs>
  <TabItem label="Next.js">
  ```bash
  sst dev next dev
  ```
  </TabItem>
  <TabItem label="Remix">
  ```bash
  sst dev remix dev
  ```
  </TabItem>
  <TabItem label="Astro">
  ```bash
  sst dev astro dev
  ```
  </TabItem>
  <TabItem label="Function">
  ```bash
  sst dev
  ```
  </TabItem>
</Tabs>

---

## How it works

At high level when you link a resource to a function or frontend, the following happens:

1. The _links_ that the resource exposes are injected into the function package.

   :::tip
   The links a component exposes are listed in its API reference. For example, you can [view a Bucket's links here](/docs/component/aws/bucket/#links).
   :::

2. The types to access these links are generated.

3. The function is given permission to access the linked resource.

---

### Injecting links

Resource links are injected into your function or frontend package when you run `sst dev` or `sst deploy`. But this is done in a slightly different way for both these cases.

#### Functions

The functions in SST are tree shaken and bundled using [esbuild](https://esbuild.github.io/). While bundling, SST injects the resource links into the [`globalThis`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis). These are encrypted and added to the function bundle. And they are synchronously decrypted on load by the SST SDK.

#### Frontends

The frontends are not bundled by SST. Instead, when they are built, SST injects the resource links into the `process.env` object using the prefix `SST_RESOURCE_`.

This is why when you are running your frontend locally, it needs to be wrapped in the `sst dev` command.

:::note
Links are only available on the server of your frontend.
:::

Resource links are only available on the server-side of your frontend. If you want to access them in your client components, you'll need to pass them in explicitly.

---

### Generating types

When you run `sst dev` or `sst deploy`, it generates the types to access the linked resources. These are generated as:

2. A `sst-env.d.ts` file in the project root with types for **all** the linked resources in the app.
1. A `sst-env.d.ts` file in the same directory of the nearest `package.json` of the function or frontend that's _receiving_ the links. This references the root `sst-env.d.ts` file.

You can check the generated `sst-env.d.ts` types into source control. This will let your teammates see the types without having to run `sst dev` when they pull your changes.

---

## Extending linking

The examples above are built into SST's components. You might want to modify the permissions that are granted as a part of these links.

Or, you might want to link other resources from the Pulumi/Terraform ecosystem. Or want to link a different set of outputs than what SST exposes.

You can do this using the [`sst.Linkable`](/docs/component/linkable/) component.

---

### Link any value

The `Linkable` component takes a list of properties that you want to link. These can be
outputs from other resources or constants.

```ts title="sst.config.ts"
const myLinkable = new sst.Linkable("MyLinkable", {
  properties: { foo: "bar" }
});
```

You can optionally include permissions or bindings for the linked resource.

Now you can now link this resource to your frontend or a function.

```ts title="sst.config.ts" {3}
new sst.aws.Function("MyApi", {
  handler: "src/lambda.handler",
  link: [myLinkable]
});
```

Then use the [SDK](/docs/reference/sdk/) to access that at runtime.

```js title="src/lambda.ts"
import { Resource } from "sst";

console.log(Resource.MyLinkable.foo);
```

Read more about [`sst.Linkable`](/docs/component/linkable/).

---

### Link any resource

You can also wrap any resource class to make it linkable with the `Linkable.wrap` static method.

```ts title="sst.config.ts"
Linkable.wrap(aws.dynamodb.Table, (table) => ({
  properties: { tableName: table.name }
}));
```

Now you create an instance of `aws.dynamodb.Table` and link it in your app like any other SST
component.

```ts title="sst.config.ts" {7}
const table = new aws.dynamodb.Table("MyTable", {
  attributes: [{ name: "id", type: "S" }],
  hashKey: "id"
});

new sst.aws.Nextjs("MyWeb", {
  link: [table]
});
```

And use the [SDK](/docs/reference/sdk/) to access it at runtime.

```js title="app/page.tsx"
import { Resource } from "sst";

console.log(Resource.MyTable.tableName);
```

---

### Modify built-in links

You can also modify the links SST creates. For example, you might want to change the permissions of a linkable resource.

```ts title="sst.config.ts" "sst.aws.Bucket"
 sst.Linkable.wrap(sst.aws.Bucket, (bucket) => ({
   properties: { name: bucket.name },
   include: [
     sst.aws.permission({
       actions: ["s3:GetObject"],
       resources: [bucket.arn]
     })
   ]
 }));
 ```

 This overrides the existing link and lets you create your own.

Read more about [`sst.Linkable.wrap`](/docs/component/linkable/#static-wrap).
